Imports Microsoft.VisualBasic
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Web

Public Class JInLineChart
    Public Enum Type As Integer
        Line = 1
        Bar = 2
    End Enum

    Private miImageWidth As Integer = 100
    Private miImageHeight As Integer = 30

    Private miChartX As Integer = 3
    Private miChartY As Integer = 3

    Private miLineWidth As Integer = 3

    Private miChartWidth As Integer = miImageWidth - miChartX * 2
    Private miChartHeight As Integer = miImageHeight - miChartY * 2

    Private moForegroundColor As Color = Color.Black
    Private moBackgroundColor As Color = Color.White

    Private mlChartType As Type
    Private mdData() As Decimal

    Private miCount As Integer
    Private mdMin As Decimal
    Private mdMax As Decimal

    Public Property ChartType() As Type
        Get
            Return mlChartType
        End Get
        Set(ByVal value As Type)
            mlChartType = value
        End Set
    End Property

    Public WriteOnly Property Data() As String()
        Set(ByVal value As String())
            miCount = value.GetUpperBound(0)
            mdMin = 0
            mdMax = 0

            ReDim mdData(miCount)
            For i As Integer = 0 To miCount
                If IsNumeric(value(i)) Then
                    mdData(i) = Val(value(i))

                    If mdData(i) > mdMax Then
                        mdMax = mdData(i)
                    End If

                    If mdData(i) < mdMin Then
                        mdMin = mdData(i)
                    End If
                Else
                    mdData(i) = 0
                End If
            Next

            mdMin = mdMin * 0.6
        End Set
    End Property

    Public WriteOnly Property Width() As Integer
        Set(ByVal value As Integer)
            miImageWidth = value
            miChartWidth = miImageWidth - miChartX * 2
        End Set
    End Property

    Public WriteOnly Property Height() As Integer
        Set(ByVal value As Integer)
            miImageHeight = value
            miChartHeight = miImageHeight - miChartY * 2
        End Set
    End Property

    Public WriteOnly Property LineHeight() As Integer
        Set(ByVal value As Integer)
            miLineWidth = value
        End Set
    End Property

    Public WriteOnly Property ForegroundColor() As String
        Set(ByVal value As String)
            moForegroundColor = HTMLColorToColor(value)
        End Set
    End Property

    Public WriteOnly Property BackgroundColor() As String
        Set(ByVal value As String)
            moBackgroundColor = HTMLColorToColor(value)
        End Set
    End Property

    Public Sub ShowChart()
        '---Create new image for composite
        Dim oImage As Bitmap = New Bitmap(miImageWidth, miImageHeight, PixelFormat.Format24bppRgb)

        '---Paste in the parts
        Dim oG As Graphics = Graphics.FromImage(oImage)
        oG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias

        '---Initialize graphic
        oG.FillRectangle(New SolidBrush(moBackgroundColor), New Rectangle(0, 0, miImageWidth, miImageHeight))

        If mlChartType = Type.Line Then
            DrawLineChart(oG)
        ElseIf mlChartType = Type.Bar Then
            DrawBarChart(oG)
        End If

        HttpContext.Current.Response.ContentType = "image/JPEG"
        oImage.Save(HttpContext.Current.Response.OutputStream, ImageFormat.Jpeg)

        oG.Dispose()
        oImage.Dispose()
    End Sub

    Private Sub DrawLineChart(ByRef oG As Graphics)
        Dim iInterval As Integer = miChartWidth / (miCount + 1)

        Dim dRange As Decimal = mdMax - mdMin
        If dRange > 0 Then
            Dim iCurX As Integer = 0
            Dim iCurY As Integer = 0

            Dim iPrevX As Integer = 0
            Dim iPrevY As Integer = 0

            For iPoint As Integer = 0 To miCount
                Dim dAdjValue As Decimal = mdData(iPoint) - mdMin

                iPrevX = iCurX
                iPrevY = iCurY

                iCurX = iInterval * iPoint + (iInterval / 2)
                iCurY = miChartHeight - (miChartHeight * (dAdjValue / dRange))

                If iPoint > 0 Then
                    oG.DrawLine( _
                            New Pen(moForegroundColor, miLineWidth), _
                            miChartX + iPrevX, _
                            miChartY + iPrevY, _
                            miChartX + iCurX, _
                            miChartY + iCurY)
                End If
            Next
        End If
    End Sub

    Private Sub DrawBarChart(ByRef oG As Graphics)
        Dim iInterval As Integer = miChartWidth / (miCount + 1)

        Dim dRange As Decimal = mdMax - mdMin
        If dRange > 0 Then
            For iPoint As Integer = 0 To miCount
                Dim dAdjValue As Decimal = mdData(iPoint) - mdMin

                Dim iCurX As Integer = iInterval * iPoint + (iInterval / 2)
                Dim iCurY As Integer = miChartHeight * (dAdjValue / dRange)

                Dim oRect As New Rectangle( _
                                    miChartX + iCurX - iInterval / 2 + miLineWidth, _
                                    miChartY + (miChartHeight - iCurY), _
                                    iInterval - miLineWidth * 2, _
                                    iCurY)

                oG.FillRectangle(New SolidBrush(moForegroundColor), oRect)
            Next
        End If
    End Sub

    Private Function HTMLColorToColor(ByVal sColor As String) As Color
        Dim iRed As Integer = CLng("&H" & sColor.Substring(0, 2))
        Dim iGreen As Integer = CLng("&H" & sColor.Substring(2, 2))
        Dim iBlue As Integer = CLng("&H" & sColor.Substring(4, 2))

        Return Color.FromArgb(iRed, iGreen, iBlue)
    End Function
End Class
